#include <gio/gfiledescriptorbased.h>
#include <gio/gunixoutputstream.h>
+#define LIBSOUP_USE_UNSTABLE_REQUEST_API
+#include <libsoup/soup.h>
+#include <libsoup/soup-requester.h>
+#include <libsoup/soup-request-http.h>
#include "libglnx.h"
#include "ostree-fetcher.h"
create_pending_soup_request (OstreeFetcherPendingURI *pending,
GError **error)
{
- g_autofree char *uristr = NULL;
- SoupURI *next_mirror = NULL;
- SoupURI *uri = NULL;
+ OstreeFetcherURI *next_mirror = NULL;
+ g_autoptr(OstreeFetcherURI) uri = NULL;
g_assert (pending->mirrorlist);
g_assert (pending->mirrorlist_idx < pending->mirrorlist->len);
- next_mirror = g_ptr_array_index (pending->mirrorlist,
- pending->mirrorlist_idx);
- uristr = g_build_filename (soup_uri_get_path (next_mirror),
- pending->filename /* may be NULL */, NULL);
- uri = soup_uri_copy (next_mirror);
- soup_uri_set_path (uri, uristr);
+ next_mirror = g_ptr_array_index (pending->mirrorlist, pending->mirrorlist_idx);
+ if (pending->filename)
+ uri = _ostree_fetcher_uri_new_subpath (next_mirror, pending->filename);
g_clear_object (&pending->request);
pending->request = soup_session_request_uri (pending->thread_closure->session,
- uri, error);
- soup_uri_free (uri);
+ (SoupURI*)(uri ? uri : next_mirror), error);
}
static void
/* Helper for callers who just want to fetch single one-off URIs */
gboolean
_ostree_fetcher_request_uri_to_membuf (OstreeFetcher *fetcher,
- SoupURI *uri,
+ OstreeFetcherURI *uri,
gboolean add_nul,
gboolean allow_noent,
GBytes **out_contents,
out_contents, max_size,
cancellable, error);
}
+
+void
+_ostree_fetcher_uri_free (OstreeFetcherURI *uri)
+{
+ if (uri)
+ soup_uri_free ((SoupURI*)uri);
+}
+
+OstreeFetcherURI *
+_ostree_fetcher_uri_parse (const char *str,
+ GError **error)
+{
+ SoupURI *soupuri = soup_uri_new (str);
+ if (soupuri == NULL)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Failed to parse uri: %s", str);
+ return NULL;
+ }
+ return (OstreeFetcherURI*)soupuri;
+}
+
+static OstreeFetcherURI *
+_ostree_fetcher_uri_new_path_internal (OstreeFetcherURI *uri,
+ gboolean extend,
+ const char *path)
+{
+ SoupURI *newuri = soup_uri_copy ((SoupURI*)uri);
+ if (path)
+ {
+ if (extend)
+ {
+ const char *origpath = soup_uri_get_path ((SoupURI*)uri);
+ g_autofree char *newpath = g_build_filename (origpath, path, NULL);
+ soup_uri_set_path (newuri, newpath);
+ }
+ else
+ {
+ soup_uri_set_path (newuri, path);
+ }
+ }
+ return (OstreeFetcherURI*)newuri;
+}
+
+OstreeFetcherURI *
+_ostree_fetcher_uri_new_path (OstreeFetcherURI *uri,
+ const char *path)
+{
+ return _ostree_fetcher_uri_new_path_internal (uri, FALSE, path);
+}
+
+OstreeFetcherURI *
+_ostree_fetcher_uri_new_subpath (OstreeFetcherURI *uri,
+ const char *subpath)
+{
+ return _ostree_fetcher_uri_new_path_internal (uri, TRUE, subpath);
+}
+
+OstreeFetcherURI *
+_ostree_fetcher_uri_clone (OstreeFetcherURI *uri)
+{
+ return _ostree_fetcher_uri_new_subpath (uri, NULL);
+}
+
+char *
+_ostree_fetcher_uri_get_scheme (OstreeFetcherURI *uri)
+{
+ return g_strdup (soup_uri_get_scheme ((SoupURI*)uri));
+}
+
+char *
+_ostree_fetcher_uri_get_path (OstreeFetcherURI *uri)
+{
+ return g_strdup (soup_uri_get_path ((SoupURI*)uri));
+}
+
+char *
+_ostree_fetcher_uri_to_string (OstreeFetcherURI *uri)
+{
+ return soup_uri_to_string ((SoupURI*)uri, FALSE);
+}
{
GObject parent_instance;
- SoupURI *uri;
+ OstreeFetcherURI *uri;
OstreeFetcher *fetcher;
char *requested_file;
case OSTREE_METALINK_STATE_URL:
{
g_autofree char *uri_text = g_strndup (text, text_len);
- SoupURI *uri = soup_uri_new (uri_text);
+ OstreeFetcherURI *uri = _ostree_fetcher_uri_parse (uri_text, NULL);
if (uri != NULL)
g_ptr_array_add (self->urls, uri);
}
g_object_unref (self->fetcher);
g_free (self->requested_file);
- soup_uri_free (self->uri);
+ _ostree_fetcher_uri_free (self->uri);
G_OBJECT_CLASS (_ostree_metalink_parent_class)->finalize (object);
}
_ostree_metalink_new (OstreeFetcher *fetcher,
const char *requested_file,
guint64 max_size,
- SoupURI *uri)
+ OstreeFetcherURI *uri)
{
OstreeMetalink *self = (OstreeMetalink*)g_object_new (OSTREE_TYPE_METALINK, NULL);
self->fetcher = g_object_ref (fetcher);
self->requested_file = g_strdup (requested_file);
self->max_size = max_size;
- self->uri = soup_uri_copy (uri);
-
+ self->uri = _ostree_fetcher_uri_clone (uri);
+
return self;
}
static gboolean
try_one_url (OstreeMetalinkRequest *self,
- SoupURI *uri,
+ OstreeFetcherURI *uri,
GBytes **out_data,
GError **error)
{
static gboolean
try_metalink_targets (OstreeMetalinkRequest *self,
- SoupURI **out_target_uri,
+ OstreeFetcherURI **out_target_uri,
GBytes **out_data,
GError **error)
{
gboolean ret = FALSE;
- SoupURI *target_uri = NULL;
+ OstreeFetcherURI *target_uri = NULL;
g_autoptr(GBytes) ret_data = NULL;
if (!self->found_a_file_element)
ret = TRUE;
if (out_target_uri)
- *out_target_uri = soup_uri_copy (target_uri);
+ *out_target_uri = _ostree_fetcher_uri_clone (target_uri);
if (out_data)
*out_data = g_steal_pointer (&ret_data);
out:
typedef struct
{
- SoupURI **out_target_uri;
+ OstreeFetcherURI **out_target_uri;
GBytes **out_data;
gboolean success;
GError **error;
gboolean
_ostree_metalink_request_sync (OstreeMetalink *self,
- SoupURI **out_target_uri,
+ OstreeFetcherURI **out_target_uri,
GBytes **out_data,
GCancellable *cancellable,
GError **error)
g_main_context_push_thread_default (mainctx);
request.metalink = g_object_ref (self);
- request.urls = g_ptr_array_new_with_free_func ((GDestroyNotify) soup_uri_free);
+ request.urls = g_ptr_array_new_with_free_func ((GDestroyNotify) _ostree_fetcher_uri_free);
request.parser = g_markup_parse_context_new (&metalink_parser, G_MARKUP_PREFIX_ERROR_POSITION, &request, NULL);
if (!_ostree_fetcher_request_uri_to_membuf (self->fetcher,
static gboolean
fetch_uri_contents_utf8_sync (OstreeFetcher *fetcher,
- SoupURI *uri,
+ OstreeFetcherURI *uri,
char **out_contents,
GCancellable *cancellable,
GError **error)
gboolean ret = FALSE;
g_auto(GStrv) lines = NULL;
g_autofree char *contents = NULL;
- SoupURI *mirrorlist = NULL;
+ g_autoptr(OstreeFetcherURI) mirrorlist = NULL;
g_autoptr(GPtrArray) ret_mirrorlist =
- g_ptr_array_new_with_free_func ((GDestroyNotify) soup_uri_free);
+ g_ptr_array_new_with_free_func ((GDestroyNotify) _ostree_fetcher_uri_free);
- mirrorlist = soup_uri_new (mirrorlist_url);
- if (mirrorlist == NULL)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Failed to parse mirrorlist URL '%s'", mirrorlist_url);
- goto out;
- }
+ mirrorlist = _ostree_fetcher_uri_parse (mirrorlist_url, error);
+ if (!mirrorlist)
+ goto out;
if (!fetch_uri_contents_utf8_sync (fetcher, mirrorlist, &contents,
cancellable, error))
for (char **iter = lines; iter && *iter; iter++)
{
const char *mirror_uri_str = *iter;
- SoupURI *mirror_uri = NULL;
+ g_autoptr(OstreeFetcherURI) mirror_uri = NULL;
+ g_autofree char *scheme = NULL;
/* let's be nice and support empty lines and comments */
if (*mirror_uri_str == '\0' || *mirror_uri_str == '#')
continue;
- mirror_uri = soup_uri_new (mirror_uri_str);
- if (mirror_uri == NULL)
+ mirror_uri = _ostree_fetcher_uri_parse (mirror_uri_str, NULL);
+ if (!mirror_uri)
{
g_debug ("Can't parse mirrorlist line '%s'", mirror_uri_str);
continue;
}
- else if ((strcmp (soup_uri_get_scheme (mirror_uri), "http") != 0) &&
- (strcmp (soup_uri_get_scheme (mirror_uri), "https") != 0))
+
+ scheme = _ostree_fetcher_uri_get_scheme (mirror_uri);
+ if (!(g_str_equal (scheme, "http") || (g_str_equal (scheme, "https"))))
{
/* let's not support mirrorlists that contain non-http based URIs for
* now (e.g. local URIs) -- we need to think about if and how we want
* to support this since we set up things differently depending on
* whether we're pulling locally or not */
g_debug ("Ignoring non-http/s mirrorlist entry '%s'", mirror_uri_str);
- soup_uri_free (mirror_uri);
continue;
}
if (ret_mirrorlist->len == 0)
{
GError *local_error = NULL;
- g_autofree char *config_uri_str = g_build_filename (mirror_uri_str,
- "config", NULL);
- SoupURI *config_uri = soup_uri_new (config_uri_str);
+ g_autoptr(OstreeFetcherURI) config_uri = _ostree_fetcher_uri_new_subpath (mirror_uri, "config");
if (fetch_uri_contents_utf8_sync (fetcher, config_uri, NULL,
cancellable, &local_error))
mirror_uri_str, local_error->message);
g_clear_error (&local_error);
}
-
- soup_uri_free (config_uri);
}
else
{
g_ptr_array_add (ret_mirrorlist, g_steal_pointer (&mirror_uri));
}
-
- if (mirror_uri != NULL)
- soup_uri_free (mirror_uri);
}
if (ret_mirrorlist->len == 0)
ret = TRUE;
out:
- if (mirrorlist != NULL)
- soup_uri_free (mirrorlist);
return ret;
}
}
else
{
- SoupURI *uri = soup_uri_new (url_string);
+ g_autoptr(OstreeFetcherURI) uri = _ostree_fetcher_uri_parse (url_string, error);
- if (uri == NULL)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Failed to parse url '%s'", url_string);
- goto out;
- }
+ if (!uri)
+ goto out;
mirrorlist =
- g_ptr_array_new_with_free_func ((GDestroyNotify) soup_uri_free);
- g_ptr_array_add (mirrorlist, uri /* transfer ownership */ );
+ g_ptr_array_new_with_free_func ((GDestroyNotify) _ostree_fetcher_uri_free);
+ g_ptr_array_add (mirrorlist, g_steal_pointer (&uri));
}
}
}
else
{
- SoupURI *baseuri = soup_uri_new (baseurl);
+ g_autoptr(OstreeFetcherURI) baseuri = _ostree_fetcher_uri_parse (baseurl, error);
- if (baseuri == NULL)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Failed to parse url '%s'", baseurl);
- goto out;
- }
+ if (!baseuri)
+ goto out;
pull_data->meta_mirrorlist =
- g_ptr_array_new_with_free_func ((GDestroyNotify) soup_uri_free);
- g_ptr_array_add (pull_data->meta_mirrorlist, baseuri /* transfer */);
+ g_ptr_array_new_with_free_func ((GDestroyNotify) _ostree_fetcher_uri_free);
+ g_ptr_array_add (pull_data->meta_mirrorlist, g_steal_pointer (&baseuri));
}
}
else
{
g_autoptr(GBytes) summary_bytes = NULL;
- SoupURI *metalink_uri = soup_uri_new (metalink_url_str);
- SoupURI *target_uri = NULL;
-
+ g_autoptr(OstreeFetcherURI) metalink_uri = _ostree_fetcher_uri_parse (metalink_url_str, error);
+ g_autoptr(OstreeFetcherURI) target_uri = NULL;
+
if (!metalink_uri)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Invalid metalink URL: %s", metalink_url_str);
- goto out;
- }
-
+ goto out;
+
metalink = _ostree_metalink_new (pull_data->fetcher, "summary",
OSTREE_MAX_METADATA_SIZE, metalink_uri);
- soup_uri_free (metalink_uri);
if (! _ostree_metalink_request_sync (metalink,
&target_uri,
* mirrors here since we use it as such anyway (rather than the "usual"
* use case of metalink, which is only for a single target filename) */
{
- /* reuse target_uri and take ownership */
- g_autofree char *repo_base = g_path_get_dirname (soup_uri_get_path (target_uri));
- soup_uri_set_path (target_uri, repo_base);
+ g_autofree char *path = _ostree_fetcher_uri_get_path (target_uri);
+ g_autofree char *basepath = g_path_get_dirname (path);
+ g_autoptr(OstreeFetcherURI) new_target_uri = _ostree_fetcher_uri_new_path (target_uri, basepath);
pull_data->meta_mirrorlist =
- g_ptr_array_new_with_free_func ((GDestroyNotify) soup_uri_free);
- g_ptr_array_add (pull_data->meta_mirrorlist, target_uri);
+ g_ptr_array_new_with_free_func ((GDestroyNotify) _ostree_fetcher_uri_free);
+ g_ptr_array_add (pull_data->meta_mirrorlist, g_steal_pointer (&new_target_uri));
}
pull_data->summary = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT,
}
else
{
- SoupURI *contenturi = soup_uri_new (contenturl);
+ g_autoptr(OstreeFetcherURI) contenturi = _ostree_fetcher_uri_parse (contenturl, error);
- if (contenturi == NULL)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Failed to parse contenturl '%s'", contenturl);
- goto out;
- }
+ if (!contenturi)
+ goto out;
pull_data->content_mirrorlist =
- g_ptr_array_new_with_free_func ((GDestroyNotify) soup_uri_free);
+ g_ptr_array_new_with_free_func ((GDestroyNotify) _ostree_fetcher_uri_free);
g_ptr_array_add (pull_data->content_mirrorlist,
- contenturi /* transfer */);
+ g_steal_pointer (&contenturi));
}
}
}
&configured_branches, error))
goto out;
+ /* TODO reindent later */
+ { OstreeFetcherURI *first_uri = pull_data->meta_mirrorlist->pdata[0];
+ g_autofree char *first_scheme = _ostree_fetcher_uri_get_scheme (first_uri);
+
/* NB: we don't support local mirrors in mirrorlists, so if this passes, it
* means that we're not using mirrorlists (see also fetch_mirrorlist()) */
- if (strcmp (soup_uri_get_scheme (pull_data->meta_mirrorlist->pdata[0]), "file") == 0)
+ if (g_str_equal (first_scheme, "file"))
{
- g_autoptr(GFile) remote_repo_path =
- g_file_new_for_path (soup_uri_get_path (pull_data->meta_mirrorlist->pdata[0]));
+ g_autofree char *path = _ostree_fetcher_uri_get_path (first_uri);
+ g_autoptr(GFile) remote_repo_path = g_file_new_for_path (path);
pull_data->remote_repo_local = ostree_repo_new (remote_repo_path);
if (!ostree_repo_open (pull_data->remote_repo_local, cancellable, error))
goto out;
goto out;
}
}
+ }
/* For local pulls, default to disabling static deltas so that the
* exact object files are copied.